<template>
    <view>
        <view class="upload-field" v-if="imageAbs">
            <view class="label-container u-flex u-row-left u-col-center">
                <text class="label-text">{{title}}</text>
                <text class="required-mark" v-if="require">*</text>
            </view>
            <view class="upload-tips">{{tips}}</view>
            <view class="upload-container">
                <view class="image-list u-flex u-flex-wrap">
                    <view class="image-item" v-for="(value,index) in imageAbs" :key="index">
                        <image :src="value" mode="aspectFill" class="upload-image" @click="previewImg(value)" />
                        <view class="delete-btn u-flex u-row-center u-col-center" @click="delImg(index)">
                            <text class="icon delete-icon">×</text>
                        </view>
                    </view>
                    <view class="upload-btn u-flex u-row-center u-col-center" @click="uploadImg(index)"
                        v-if="imageAbs.length < 5">
                        <view class="upload-icon-container">
                            <text class="icon upload-icon">+</text>
                            <text class="upload-text">{{btnTitle}}</text>
                        </view>
                    </view>
                </view>
            </view>
        </view>
    </view>
</template>

<script>
    /**
     * 图片上传、预览
     * @description 此组件一般用于图片上传、预览。
     * @tutorial https://www.dfer.site
     * @property {Array} imageAbsInit 绝对路径的初始值
     * @property {String} uploadApi 图片上传接口地址
     * @event {Function} resultHandler 上传接口返回数据之后触发
     * @example <dfer-upload-img @resultHandler="resultImg" @uploadingHandler="uploadingImg" :uploadApi="$puburl + 'resource/formupload'" :title="item.name" :tips="item.title" :require="item.mandatory==1" :params="{token: token}" :extend="index" :trace="true" />
     */
    export default {
        name: "dfer-upload-img",
        data() {
            return {
                // 绝对路径。
                imageAbs: [],
                // 相对路径。
                imageRel: [],
                // 最终结果。用逗号分隔多个图片路径
                result: "",
                isInit: false
            };
        },
        props: {
            trace: {
                type: Boolean,
                default () {
                    return false
                }
            },
            needInit: {
                type: Boolean,
                default: false
            },
            require: {
                type: Boolean,
                default: false
            },
            imageAbsInit: {
                type: [Array, String, Number, Object],
                default: []
            },
            title: {
                type: String,
                default: "图片"
            },
            btnTitle: {
                type: String,
                default: "上传"
            },
            tips: {
                type: String,
                default: "最多上传5张图片，支持JPG、PNG格式"
            },
            uploadApi: {
                type: String,
                default: "https://api.dfer.site/upload"
            },
            params: {
                type: [Array, String, Number, Object],
                default: {
                    token: 'dfer.site'
                }
            },
            extend: {
                type: [Array, String, Number, Object],
            }
        },
        watch: {
            imageAbsInit: {
                handler(newVal) {
                    if (newVal && this.isInit) {
                        this.imageAbs = newVal;
                        if (this.trace)
                            console.log('imageAbsInit', this.imageAbs, this.isInit);
                    }
                },
                immediate: true
            },
            needInit: {
                handler(newVal) {
                    this.isInit = newVal;
                },
                immediate: true
            }
        },
        created() {
            if (this.trace)
                console.log(this.needInit);
        },
        methods: {
            // ********************** 图片 START **********************
            previewImg(url) {
                // 预览一张图片
                let urls = [url];
                uni.previewImage({
                    current: 0,
                    urls: urls
                })
            },
            delImg(index) {
                // 在图片编号处清理一张图片
                this.imageRel.splice(index, 1);
                this.imageAbs.splice(index, 1);
                this.saveResult();
            },
            uploadImg() {
                let _this = this;
                this.isUploading(true);
                if (_this.imageAbs.length >= 5) {
                    uni.showToast({
                        title: '最多只能上传5张图片',
                        icon: "none",
                        duration: 2000
                    });
                    return false;
                }
                uni.chooseImage({
                    count: 1,
                    success: (chooseImageRes) => {
                        const tempFilePaths = chooseImageRes.tempFilePaths;
                        if (this.trace)
                            console.log(tempFilePaths, _this.uploadApi);
                        uni.uploadFile({
                            url: _this.uploadApi,
                            filePath: tempFilePaths[0],
                            name: 'file',
                            fileType: "image",
                            formData: _this.params,
                            success: (res) => {
                                var res = JSON.parse(res.data);
                                if (res.code == 0) {
                                    // 保存新图片到路径中
                                    _this.imageRel = _this.imageRel.concat(res.data.rel_path);
                                    _this.imageAbs = _this.imageAbs.concat(res.data.abs_path);
                                    _this.saveResult();
                                }
                                _this.showToast(res.message);
                            }
                        });
                    },
                    complete: () => {
                        this.isUploading(false);
                    }
                });
            },
            saveResult() {
                this.result = this.imageAbs;
                if (this.trace)
                    console.log(this.result, this.extend);
                this.$emit('resultHandler', this.result, this.extend);
            },
            isUploading($value) {
                this.$emit('uploadingHandler', $value);
            }

            // **********************  图片 END  **********************
        }
    }
</script>

<style lang="scss">
    .upload-tips {
        font-size: 26rpx;
        color: #999999;
        margin-bottom: 16rpx;
    }

    .upload-container {
        margin-top: 10rpx;
    }

    .image-list {
        margin-top: 10rpx;
    }

    .image-item {
        position: relative;
        margin-right: 20rpx;
        margin-bottom: 20rpx;
    }

    .upload-image {
        width: 160rpx;
        height: 160rpx;
        border-radius: 12rpx;
    }

    .delete-btn {
        position: absolute;
        top: -16rpx;
        right: -16rpx;
        width: 40rpx;
        height: 40rpx;
        background-color: #ff3b30;
        border-radius: 50%;
        box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.2);
    }

    .delete-icon {
        font-size: 28rpx;
        color: #ffffff;
        font-weight: bold;
    }

    .upload-btn {
        width: 160rpx;
        height: 160rpx;
        border: 2rpx dashed #d9d9d9;
        border-radius: 12rpx;
        background-color: #fafafa;
        transition: all 0.2s;
    }

    .upload-btn:active {
        border-color: #1a6cdf;
        background-color: #f0f7ff;
    }

    .upload-icon-container {
        text-align: center;
    }

    .upload-icon {
        font-size: 48rpx;
        color: #999999;
        display: block;
    }

    .upload-text {
        font-size: 24rpx;
        color: #999999;
        margin-top: 8rpx;
    }
</style>